#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/ledc.h"
#include "esp_err.h"

#define LEDC_TIMER          LEDC_TIMER_0
#define LEDC_MODE           LEDC_HIGH_SPEED_MODE
#define LEDC_OUTPUT_IO_0    (12) // GPIO number for LEDC channel 0
#define LEDC_OUTPUT_IO_1    (13) // GPIO number for LEDC channel 1
#define LEDC_OUTPUT_IO_2    (14) // GPIO number for LEDC channel 2
#define LEDC_CHANNEL_0      LEDC_CHANNEL_0
#define LEDC_CHANNEL_1      LEDC_CHANNEL_1
#define LEDC_CHANNEL_2      LEDC_CHANNEL_2
#define LEDC_DUTY_RES       LEDC_TIMER_13_BIT // Set duty resolution to 13 bits
#define LEDC_FREQUENCY      (5000) // Frequency in Hertz. Set frequency at 5 kHz

void app_main(void)
{
    // 配置LEDC定时器
    ledc_timer_config_t ledc_timer = {
        .speed_mode       = LEDC_MODE,
        .timer_num        = LEDC_TIMER,
        .duty_resolution  = LEDC_DUTY_RES,
        .freq_hz          = LEDC_FREQUENCY,
        .clk_cfg          = LEDC_AUTO_CLK
    };
    ledc_timer_config(&ledc_timer);

    // 配置三个LEDC通道，每个通道共享同一个定时器
    ledc_channel_config_t ledc_channel[3] = {
        {
            .speed_mode     = LEDC_MODE,
            .channel        = LEDC_CHANNEL_0,
            .timer_sel      = LEDC_TIMER,
            .intr_type      = LEDC_INTR_FADE_END,
            .gpio_num       = LEDC_OUTPUT_IO_0,
            .duty           = 0, // 初始占空比
            .hpoint         = 0
        },
        {
            .speed_mode     = LEDC_MODE,
            .channel        = LEDC_CHANNEL_1,
            .timer_sel      = LEDC_TIMER,
            .intr_type      = LEDC_INTR_FADE_END,
            .gpio_num       = LEDC_OUTPUT_IO_1,
            .duty           = 0, // 初始占空比
            .hpoint         = 0
        },
        {
            .speed_mode     = LEDC_MODE,
            .channel        = LEDC_CHANNEL_2,
            .timer_sel      = LEDC_TIMER,
            .intr_type      = LEDC_INTR_FADE_END,
            .gpio_num       = LEDC_OUTPUT_IO_2,
            .duty           = 0, // 初始占空比
            .hpoint         = 0
        }
    };

    // 设置LEDC通道
    for (int ch = 0; ch < 3; ch++) {
        ledc_channel_config(&ledc_channel[ch]);
    }

    // 初始化淡入淡出服务
    ledc_fade_func_install(0);

    while (1) {
        // 红色
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_0, 8191, 1000); // 100% 占空比
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_1, 0, 1000);    // 0% 占空比
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_2, 0, 1000);    // 0% 占空比
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT);
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_1, LEDC_FADE_NO_WAIT);
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_2, LEDC_FADE_NO_WAIT);
        vTaskDelay(1000 / portTICK_PERIOD_MS);

        // 绿色
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_0, 0, 1000);
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_1, 8191, 1000);
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_2, 0, 1000);
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT);
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_1, LEDC_FADE_NO_WAIT);
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_2, LEDC_FADE_NO_WAIT);
        vTaskDelay(1000 / portTICK_PERIOD_MS);

        // 蓝色
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_0, 0, 1000);
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_1, 0, 1000);
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_2, 8191, 1000);
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT);
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_1, LEDC_FADE_NO_WAIT);
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_2, LEDC_FADE_NO_WAIT);
        vTaskDelay(1000 / portTICK_PERIOD_MS);

        // 黄色
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_0, 8191, 1000);
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_1, 8191, 1000);
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_2, 0, 1000);
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT);
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_1, LEDC_FADE_NO_WAIT);
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_2, LEDC_FADE_NO_WAIT);
        vTaskDelay(1000 / portTICK_PERIOD_MS);

        // 紫色
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_0, 8191, 1000);
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_1, 0, 1000);
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_2, 8191, 1000);
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT);
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_1, LEDC_FADE_NO_WAIT);
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_2, LEDC_FADE_NO_WAIT);
        vTaskDelay(1000 / portTICK_PERIOD_MS);

        // 青色
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_0, 0, 1000);
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_1, 8191, 1000);
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_2, 8191, 1000);
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT);
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_1, LEDC_FADE_NO_WAIT);
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_2, LEDC_FADE_NO_WAIT);
        vTaskDelay(1000 / portTICK_PERIOD_MS);

        // 白色
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_0, 8191, 1000);
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_1, 8191, 1000);
        ledc_set_fade_with_time(LEDC_MODE, LEDC_CHANNEL_2, 8191, 1000);
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_0, LEDC_FADE_NO_WAIT);
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_1, LEDC_FADE_NO_WAIT);
        ledc_fade_start(LEDC_MODE, LEDC_CHANNEL_2, LEDC_FADE_NO_WAIT);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}
